# mergebuffers.S 							
# 								
# - Argumentos:							
# 	* a0: dirección inicial de buffer1.		
#	* a1: tamaño de buffer1.
# 	* a2: dirección inicial de buffer2.		
#	* a3: tamaño de buffer2.
#	* stack: dirección inicial de memoria para guardar el buffer resultante.
#								
# - No devuelve ningún valor de retorno. 			
#								
# - Stack frame: 16 bytes para el SRA + padding. Por ser función hoja, no reserva espacio para ABA.
										

#include <mips/regdef.h>
#include <sys/syscall.h>

#define 	SSIZE 	(16)

#define		O_FP 	(8)
#define		O_GP	(4)
#define 	O_S4 	(0)

#define 	O_ARG0	(SSIZE)
#define 	O_ARG1	((SSIZE) + 4)
#define 	O_ARG2	((SSIZE) + 8)
#define 	O_ARG3	((SSIZE) + 12)
#define 	O_ARG4	((SSIZE) + 16)


#void mergeBuffers (char* buffer1, int tamanioBuffer1, char* buffer2, int tamanioBuffer2, char* salida)

	.text
	.align 	2
	.globl	merge_buffers
	.ent	merge_buffers

merge_buffers:
   	.frame $fp, SSIZE, ra
   	.set noreorder
   	.cpload t9
   	.set reorder     
	
		subu	sp,sp,SSIZE 		#crea el stack.

		sw 	s4, O_S4(sp)

		#sw	gp, O_GP(sp)
		.cprestore O_GP
		sw	$fp, O_FP(sp) 
		
		move	$fp, sp

		sw	a0, O_ARG0($fp)
		sw	a1, O_ARG1($fp)
		sw	a2, O_ARG2($fp)
		sw	a3, O_ARG3($fp)
		lw 	s4, O_ARG4($fp) 	#recupera el 5to argumento del stack en s4

		move 	t1, zero 		#pBuffer1 = 0
		move 	t2, zero 		#pBuffer2 = 0
		move 	t0, zero 		#pSalida = 0 (son los índices para recorrer los buffers)

BUCLE_PPAL:	beq 	t1, a1, BUCLE_BUFF1 	#chequea las dos condiciones del bucle principal
		beq 	t2, a3, BUCLE_BUFF1
		
		addu 	t6, t1, a0
		addu 	t7, t2, a2		

		lb 	t3, 0(t6) 		#t3 es buffer1[pBuffer1]
		lb 	t4, 0(t7) 		#t4 es buffer2[pBuffer2]
		sub 	t5, t4, t3
		blez 	t5, ELSE

		addu 	t8, t0, s4
		sb 	t3, 0(t8)
		addiu 	t1, t1, 1
		b 	FIN_DEL_CICLO

ELSE:		addu 	t8, t0, s4
		sb 	t4, 0(t8)
		addiu 	t2, t2, 1

FIN_DEL_CICLO: 	addiu 	t0, t0, 1
		b 	BUCLE_PPAL


BUCLE_BUFF1: 	beq 	t1, a1, BUCLE_BUFF2

		addu 	t6, t1, a0
		addu 	t8, t0, s4

		lb 	t3, 0(t6)
		sb 	t3, 0(t8)

		addiu 	t1, t1, 1
		addiu 	t0, t0, 1

		b 	BUCLE_BUFF1

BUCLE_BUFF2: 	beq 	t2, a3, SALIDA

		addu 	t7, t2, a2
		addu 	t8, t0, s4

		lb 	t4, 0(t7)
		sb 	t4, 0(t8)

		addiu 	t2, t2, 1
		addiu 	t0, t0, 1

		b 	BUCLE_BUFF2

SALIDA:		move 	sp, $fp

		lw 	s4, O_S4($fp)
		lw	gp, O_GP($fp)
		lw	$fp, O_FP($fp)
		
		addiu 	sp, sp, SSIZE
		jr 	ra

	.end 	merge_buffers
